
#ifndef HAVE_IPV6
#define HAVE_IPV6 1
#endif

#include "ddc/ddc_spf.h"
#include "ddc/ddc.h"
#include "ddc/ddc_router.h"
#include "lib/prefix.h"
#include "lib/pqueue.h"
//#include "lib/memory.h"
#include "lib/linklist.h"
//#include "lsd/cr_hello.h"
//#include "ospf6d/ospf6_lsa.h"
//#include "ospf6d/ospf6_intra.h"


#define ospf6_nexthop_is_set(x)                                \
  ((x)->ifindex || ! IN6_IS_ADDR_UNSPECIFIED (&(x)->address))
struct cr_floyd_matrix* floyd_matric_before;
int length;

int cr_vertex_cmp (void *a, void *b)
{
  struct cr_vertex *va = (struct cr_vertex *) a;
  struct cr_vertex *vb = (struct cr_vertex *) b;
  /* ascending order */
  return (va->cost - vb->cost);
}

//vertex_id compare
int cr_vertex_id_cmp (void *a, void *b)
{
  struct cr_vertex *va = (struct cr_vertex *) a;
  struct cr_vertex *vb = (struct cr_vertex *) b;
  int ret = 0;

  ret = va->vertex_id-vb->vertex_id;
  if (ret)
    return ret;

  ret = va->vertex_id-vb->vertex_id;
  return ret;
}

//cr_vertex_delete
void cr_vertex_delete(struct cr_vertex *v)
{
	list_delete(v->child_list);
	free(v);
}

///root vertex create
struct cr_vertex *cr_root_vertex_create (struct cr_floyd_match *head,int length, struct cr_lsdb_link_state *lsdb_link,int a_rid)
{
  struct cr_vertex *v;
  int i;
  int id = 0;

  v = (struct cr_vertex *)malloc(sizeof (struct cr_vertex));
  v->type	=CR_VERTEX_TYPE_ROUTER;
  u_int32_t rt = search_router_id_by_num(head, length, a_rid);

  v->vertex_id = rt;
  v->a_rid		= a_rid;
  v->b_rid		= a_rid;
  memcpy(&v->vertix.u.prefix6.s6_addr[0],&rt,4);
  memcpy (&v->vertix.u.prefix6.s6_addr[4], &id, 4);
  v->vertix.family	= AF_INET6;
  v->vertix.prefixlen = 64;

  v->cost = 0;
  //memset (&v->vertix, 0, sizeof (struct prefix));
  /* Associated LSA */
  v->lsa_link = (struct cr_lsdb_link_state *)malloc(sizeof(struct cr_lsdb_link_state));
  v->lsa_link->key.rt_id = rt;
  v->lsa_link->key.if_id = 0;
  v->lsa_link->key.n_rt_id = rt;
  v->lsa_link->key.n_if_id = 0;

  for (i = 0; i < CR_MULTI_PATH_LIMIT; i++)
   {
	  memset(&v->nexthop[i].address, 0, sizeof(struct in6_addr));
	  v->nexthop[i].ifindex=0;
	  v->nexthop[i].router_id =0;
   }
  v->parent = NULL;
  v->child_list = list_new ();
  v->child_list->cmp = cr_vertex_id_cmp;
 // printf("create root vertex, root_id is %d.\n",v->vertex_id);
  return v;
}

struct cr_vertex *cr_vertex_add(struct cr_floyd_match *head,int length,struct cr_lsdb_link_state *lsdb_link,int a_rid,int b_rid)
{
	struct cr_vertex *v;
	  int i;
	  int id = 0;

	  v = (struct cr_vertex *)malloc(sizeof (struct cr_vertex));
	  v->type	=CR_VERTEX_TYPE_ROUTER;
	  v->a_rid	= a_rid;
	  v->b_rid	= b_rid;

	  int rt = search_router_id_by_num(head, length, b_rid);
	  if(rt == lsdb_link->key.n_rt_id)
	  {
		  v->vertex_id = lsdb_link->key.n_rt_id;
		  memcpy(&v->vertix.u.prefix6.s6_addr[0],&lsdb_link->key.n_rt_id,4);
		  memcpy (&v->vertix.u.prefix6.s6_addr[4], &id, 4);
	  }
	  else{
		  v->vertex_id = lsdb_link->key.rt_id;
		  memcpy(&v->vertix.u.prefix6.s6_addr[0],&lsdb_link->key.rt_id,4);
		  memcpy (&v->vertix.u.prefix6.s6_addr[4], &id, 4);
	  }
	  v->cost = 0;

	  v->vertix.family	= AF_INET6;
	  v->vertix.prefixlen = 64;
	  v->lsa_link = lsdb_link;
	  for (i = 0; i < CR_MULTI_PATH_LIMIT; i++)
	   {
		  memset(&v->nexthop[i].address, 0, sizeof(struct in6_addr));
		  v->nexthop[i].ifindex=0;
		  v->nexthop[i].router_id =0;
	   }
	  v->parent = NULL;
	  v->child_list = list_new ();
	  v->child_list->cmp = cr_vertex_id_cmp;
	  return v;
}

void cr_spf_calculation (struct cr_floyd_matrix *fm, struct cr_floyd_match	*match_head,
		int router_id,struct cr_route_table *result_table,int length)
{
  struct pqueue *candidate_list;
  struct cr_vertex *root, *v, *w;
  int j,k;

  struct cr_floyd_matrix *matrix_element;
  struct cr_lsdb_link_state *link;
  int router_mid;

  /* initialize */
   candidate_list = pqueue_create ();
   candidate_list->cmp = cr_vertex_cmp;

    //create root vertex and initial it
	//matrix_element is the first link of v.
   matrix_element = get_lsa_byRouter_mid(fm,router_id,length);
   root = cr_root_vertex_create(match_head,length,matrix_element->link,router_id);
   root->hops = 0;
   inet_pton (AF_INET6, "::1", &root->nexthop[0].address);
   /* Actually insert root to the candidate-list as the only candidate */
   pqueue_enqueue (root, candidate_list);
     while (candidate_list->size)
       {
		  v = pqueue_dequeue (candidate_list);

		//  printf("pqueue_dequeue new vertex from equeue, vertex_id is %d, and cost from is %d\n",v->vertex_id,v->cost);

		  if(floydMatrix_nexthop_install(v,result_table)<0)
		  {
			  //printf("floydMatrix_nexthop_install continue,and candidate_size is %d.\n",candidate_list->size);
			  continue;
		  }
		  /* For each LS description in the just-added vertex V's LSA */
		  // find v's all LSA
		 router_mid = cr_ddc_searchNumByRouterID(match_head,length,v->vertex_id);
		 for(j=0;j<length;j++)//j =0 is router itself.So we need to count i from 1;
		  {
			 if(router_mid==j)
			 {
				 continue;
			 }
			matrix_element= (struct cr_floyd_matrix*)((char *)fm+(router_mid*length+j)*sizeof(struct cr_floyd_matrix));
			if(matrix_element->link==NULL)
			 {
				 continue;
			 }
			link		  = matrix_element->link;

			//printf("new link info is a:%d:%d--%d:%d, metric is %d\n",link->ifa_info.rt_id,link->ifa_info.if_id,
//					link->ifb_info.rt_id,link->ifb_info.if_id,link->metric_up);

			//w= cr_vertex_create(matrix_element->link,v);
			w= cr_vertex_add(match_head, length,matrix_element->link,router_mid,j);
			w->parent	= v;
			w->cost = v->cost+matrix_element->link->metric;
			w->hops	= v->hops+1;

			/*nexthop calculation */
			if(w->hops == 0)
			{
				if(w->vertex_id == matrix_element->link->key.rt_id)
				{
					w->nexthop[0].ifindex = matrix_element->link->key.if_id;
					w->nexthop[0].router_id	= matrix_element->link->key.rt_id;
				}
				else{
					w->nexthop[0].ifindex = matrix_element->link->key.n_if_id;
					w->nexthop[0].router_id	= matrix_element->link->key.n_rt_id;
				}
			}
			else if(w->hops ==1 && v->hops ==0)// there are middle hops
			{
				cr_nexthop_calc(match_head,fm,w,v,link,length);
				//w->nexthop[0].ifindex = matrix_element->link->ifa_info.if_id;
			}
			else
			{
				for (k = 0;v->nexthop[k].router_id>=0 && k < CR_MULTI_PATH_LIMIT; k++)
				{
					w->nexthop[k].ifindex = v->nexthop[k].ifindex;
					w->nexthop[k].router_id = v->nexthop[k].router_id;
					memcpy (&w->nexthop[k].address, &v->nexthop[k].address,//need modify.20100611
												  sizeof (struct in6_addr));
					//w->nexthop[k].router_id = v->nexthop[k].router_id; meno by yangyu
				}
			}
			pqueue_enqueue(w,candidate_list);
		}//end of for
   }// end of candidate_list
 pqueue_delete(candidate_list);

 show_route_table(result_table,router_id);
 copy_nexthop(match_head, result_table, fm, length, router_id);
}

//calculate the  real nexthops.

void cr_nexthop_calc(struct cr_floyd_match *head,struct cr_floyd_matrix *fm,
		struct cr_vertex *w,struct cr_vertex *v,struct cr_lsdb_link_state *link,int length)
{
	  int i, j;
	  u_int32_t adv_router;
	  struct cr_lsdb_link_state *p_link;
	  struct cr_floyd_matrix *matrix_element;
	  //char buf[64];

	  //ifindex = link->ifa_info.if_id;
	  adv_router = w->b_rid;

	  i=0;
	  j=0;
	  int mid_id = search_num_byrouter_id(head, length, v->vertex_id);
	  while(i<length)
	  {
		matrix_element= (struct cr_floyd_matrix*)((char *)fm+(mid_id*length+i)*sizeof(struct cr_floyd_matrix));
		p_link	= matrix_element->link;
		if(p_link==NULL || p_link!=link)
		 {
			i++;
			 continue;

		 }

		while(j < CR_MULTI_PATH_LIMIT)
		{
			if(!(cr_nexthop_is_set (&w->nexthop[j])))
			{
				if(p_link->key.rt_id == v->vertex_id)
				{
					memcpy (&w->nexthop[j].address, &p_link->addr,//need modify.20100611
							  sizeof (struct in6_addr));
					w->nexthop[j].ifindex = p_link->key.if_id;
					w->nexthop[j].router_id = v->vertex_id;
				}
				else
				{
					memcpy (&w->nexthop[j].address, &p_link->key.n_rt_id,//need modify.20100611
							  sizeof (struct in6_addr));
					w->nexthop[j].ifindex = p_link->key.n_if_id;
					w->nexthop[j].ifindex = p_link->key.n_if_id;

				}
				break;
			}

		  j++;
		}
		i++;
	  }
	  return;
}//end cr_nexthop_cal




int floydMatrix_nexthop_install(struct cr_vertex *v,struct cr_route_table  *result_table)
{
	int i,j;
	struct cr_route *route;
	struct cr_vertex *prev,*w;
	listnode node;

	route = cr_route_lookup(&v->vertix,result_table);
	if(route&&(route->path.cost < v->cost))
	{
		cr_vertex_delete(v);
		return -1;
	}
	else if(route&&(route->path.cost == v->cost))//exist equal shortest path
	{
		printf("there is another shortest path.\n");
		for(i=0;(cr_nexthop_is_set(&v->nexthop[i]))&&(i<CR_MULTI_PATH_LIMIT);i++)
		{
			for(j=0;j<CR_MULTI_PATH_LIMIT;j++)
			{
				if(cr_nexthop_is_set(&route->nexthop[j]))
				{
					if(cr_nexthop_is_same(&route->nexthop[j],&v->nexthop[i]))
						break;
					else
						continue;
				}

				cr_nexthop_copy(&route->nexthop[j],&v->nexthop[i]);
				break;
			}
		}
		printf("\n ECMP is: the index is %d, cost is %d,destination is%d.%d.%d.%d\n",v->nexthop[1].ifindex,route->path.cost, route->prefix.u.prefix6.s6_addr32[0], route->prefix.u.prefix6.s6_addr32[1], route->prefix.u.prefix6.s6_addr32[2], route->prefix.u.prefix6.s6_addr32[3]);

		prev = (struct cr_vertex *)route->route_option;
		if(prev->hops > v->hops)
		{
			LIST_LOOP(prev->child_list,w,node)
			{
				w->parent = v;
				listnode_add_sort(v->child_list,w);
			}
			listnode_delete(prev->parent->child_list,prev);
			listnode_add_sort(v->parent->child_list,v);

			cr_vertex_delete(prev);
			route->route_option = v;
		}
		else
			cr_vertex_delete(v);

		return -1;
	}

		route = cr_route_create();
		memcpy(&route->prefix,&v->vertix,sizeof(struct prefix));


		route->path.origin.id = v->lsa_link->key.rt_id;
		route->path.origin.adv_router = v->lsa_link->key.n_rt_id;
		route->path.cost = v->cost;
		route->path.cost_e2 = v->hops;

		for(i=0;cr_nexthop_is_set(&v->nexthop[i])&&(i<CR_MULTI_PATH_LIMIT);i++)
			cr_nexthop_copy(&route->nexthop[i],&v->nexthop[i]);

		if(v->parent)
			listnode_add_sort(v->parent->child_list,v);
		route->route_option = v;

		route = cr_route_add(route,result_table);

		//printf("\n the index is %d, cost is %d,destination is%d.%d.%d.%d\n",route->nexthop[0].ifindex,route->path.cost, route->prefix.u.prefix6.s6_addr32[0], route->prefix.u.prefix6.s6_addr32[1], route->prefix.u.prefix6.s6_addr32[2], route->prefix.u.prefix6.s6_addr32[3]);

		//printf("\nthe nexthop is %d, cost is %d,destination is%d.%d.%d.%d\n",route->nexthop[0],route->path.cost, route->prefix.u.prefix6.in6_u.u6_addr32[0],route->prefix.u.prefix6.in6_u.u6_addr32[1],route->prefix.u.prefix6.in6_u.u6_addr32[2],route->prefix.u.prefix6.in6_u.u6_addr32[3]);

		return 0;

}


void cr_node_print(struct cr_route_table *result_table,int route_id)
{
	//printf("final nexthop from root %d to every other nodes is:\n",route_id);

	struct cr_route *route_head = result_table->table->top->info;
	struct cr_route *route_node = route_head;
	int i;

	if(route_node)
	{
		//printf("cr_path: adv_router is %d, if_id is %d , next_hop is: \n",route_node->path.origin.adv_router,route_node->path.origin.id);
		for(i = 0;i<CR_MULTI_PATH_LIMIT;i++)
		{
			//printf("%d------%d\n",route_node->nexthop[i].router_id,route_node->nexthop[i]);
		}
		route_node = route_node->next;
	}

	return ;
}



struct cr_floyd_matrix * init_floyd_matrix(struct cr_floyd_match *p_matchHead,int lsdb_handler)
{
	//struct prefix_ipv6 key_prefix;
	struct cr_floyd_matrix *strMatrixHead;
	struct cr_lsdb_link_state * cr_lsdbLinkhead, *m_link;
	struct cr_floyd_matrix *p,*pz;
	struct link_state_key	      strLink;
	int i,j,k;
	int pi,pj;
	int use;
	struct cr_lsdb_link_state *pLinkHead	;
	//u_int16_t lsa_type	=	CR_LSTYPE_ROUTER;
	//u_int32_t lsa_id		= 0;
	 //struct route_node *current;
	int p_length=cr_lsdb_get_routers_count(lsdb_handler);

	if(p_length==0)
	{
		return NULL;
	}
	strMatrixHead	= (struct cr_floyd_matrix *)malloc(p_length*p_length*sizeof(struct cr_floyd_matrix));
	if(!strMatrixHead)
	{
		return NULL;
	}
	for(i=0;i<p_length;i++)
	{
		for(j=0;j<p_length;j++)
		{
			p=(struct cr_floyd_matrix *)(strMatrixHead+(i*p_length+j));
			if(i!=j)
			{
				p->metric	= MAX_METRIC;
			}
			else
			{
				p->metric	=0;
			}
			p->nextHop	= j;
			p->link		= NULL;
			p->path		= NULL;
			for(k=0;k<CR_MULTI_PATH_LIMIT;k++)
			{
				p->nexthop[k].ifindex = 0;
				p->nexthop[k].router_id = 0;
			}
			p->route_option = (struct cr_vertex *)malloc(sizeof(struct cr_vertex));
			p->route_option = NULL;
		}
	}

	cr_lsdb_get_links_state(&cr_lsdbLinkhead, lsdb_handler);
	pLinkHead= cr_lsdbLinkhead;



	while(pLinkHead)
	{

		strLink = pLinkHead->key;
		if(strLink.n_rt_id == 0)
		{
			pLinkHead		= pLinkHead->next;
			continue;
		}
		use = 1;//wait tomodify
		//use = cr_lsd_is_connected(pLinkHead, lsdb_handler);
		if(use)
		{
			m_link = (struct cr_lsdb_link_state*)malloc(sizeof(struct cr_lsdb_link_state));
			memcpy(m_link,pLinkHead,sizeof(struct cr_lsdb_link_state));
			pi	= cr_ddc_searchNumByRouterID(p_matchHead,p_length,strLink.rt_id);
			pj	= cr_ddc_searchNumByRouterID(p_matchHead,p_length,strLink.n_rt_id);
			if(pi>=0)
			{
				i			= pi*p_length+pj;
				j			= pj*p_length+pi;
				p			= (struct cr_floyd_matrix*) ((char *)strMatrixHead+i*sizeof(struct cr_floyd_matrix));
				pz			= (struct cr_floyd_matrix*) ((char *)strMatrixHead+j*sizeof(struct cr_floyd_matrix));
				p->metric	= m_link->metric;
				p->link	= m_link;
				pz->link	= m_link;
				pz->metric	= m_link->metric;

			}
		}

		pLinkHead		= pLinkHead->next;
	}
	floyd_matric_before = strMatrixHead;

	return strMatrixHead;
}
int cr_ddc_match_sort(struct cr_floyd_match * match, int length)
{
	int i,j;
	u_int32_t temp;
	if(match==NULL)
	{
		return -1;
	}
	for(i=1;i<length;i++)
	{
		for(j=0;j<length-i;j++)
		{
			if(match[j].routerID>match[j+1].routerID)
			{
				temp	=match[j].routerID;
				match[j].routerID	= match[j+1].routerID;
				match[j+1].routerID = temp;
			}

		}
	}
	return 0;

}
struct cr_floyd_match *	init_floyd_match(int lsdb_handler)
{

	int 	lsdbNodeCount;
	struct cr_floyd_match  *strMatchHead;
	int 					i	=1;
	struct cr_lsdb_router *cr_lsdb_head;
	lsdbNodeCount		=  cr_lsdb_get_routers_count(lsdb_handler);
	length		= lsdbNodeCount;
	if(lsdbNodeCount==0)
	{
		strMatchHead = NULL;

	}
	cr_lsdb_get_routers(&cr_lsdb_head, lsdb_handler);
	strMatchHead	= (struct cr_floyd_match *)malloc(lsdbNodeCount*sizeof(struct cr_floyd_match));
	if(!strMatchHead)
	{
		strMatchHead = NULL;
	}
	for (i = 0; i <lsdbNodeCount; i++)
	{
		struct cr_lsdb_router	*p		= cr_lsdb_head;
		strMatchHead[i].routerID	= cr_lsdb_head->id;
		//strMatchHead[i].num			= i;
		cr_lsdb_head	= cr_lsdb_head->next;
		free(p);
	}
	cr_ddc_match_sort(strMatchHead,length);
	for (i = 0; i <lsdbNodeCount; i++)
	{
		strMatchHead[i].num			= i;
	}
	return strMatchHead;
}

void print_floyd(struct cr_floyd_matrix*p_matrixHead,struct cr_floyd_match *fmatch,int length,int  lsdb_handler)
{
	int i,j;
	struct cr_floyd_matrix *strP	= NULL;
	for(i=0;i<length;i++)
	{
		for(j=0;j<length;j++)
		{

			strP= (struct cr_floyd_matrix *)((char *)p_matrixHead + (i*length+j)*sizeof(struct cr_floyd_matrix));
			if(strP)
			{
				printf("%2d  ",strP->nextHop);
			}
			else
			{
				printf("%2d",99);

			}

		}
		printf("\n");
	}
}
void print_match(struct cr_floyd_match *match,int length)
{
	int i	= 0;
	for(i=0;i<length;i++)
	{
		printf("%d(%d)\n",match[i].routerID,match[i].num);

	}
}
int search_num_byrouter_id(struct cr_floyd_match *head,int length, int pRouterID)
{
	int i;
		for (i = 0; i < length; i++)
		{
			if (head[i].routerID == pRouterID)
			{
				return (head[i].num);
			}
		}
		return -1;
}
int search_router_id_by_num(struct cr_floyd_match *head,int length, int num)
{
	int i;
		for (i = 0; i < length; i++)
		{
			if (head[i].num == num)
			{
				return (head[i].routerID);
			}
		}
		return -1;
}

void nexthop_print(struct cr_floyd_matrix *matrix_head,int length)
{
	struct cr_floyd_matrix *node;
	int i;

	for(i=0;i<length;i++)
	{
		node = (struct cr_floyd_matrix *)((char*)matrix_head+i*sizeof(struct cr_floyd_matrix));
		printf("nexthop is %d\n",node->nexthop[i].router_id);
	}
}

struct cr_floyd_matrix *get_lsa_byRouter_mid(struct cr_floyd_matrix *matrix_head, int router_mid,int length)
{
	struct cr_floyd_matrix *m_element	= NULL;

	m_element = (struct cr_floyd_matrix *)((char *)matrix_head +
			(router_mid*length)*sizeof(struct cr_floyd_matrix ));

	return m_element;
}

void cr_spf_lsa_set_key (struct prefix_ipv6 *key, void *value, int len)
{
  memcpy ((caddr_t)&key->prefix + key->prefixlen / 8, (caddr_t) value, len);
  key->family = AF_INET6;
  key->prefixlen += len * 8;

  return;
}

void copy_nexthop(struct cr_floyd_match *match,struct cr_route_table *route_table,struct cr_floyd_matrix *fm,int length,int router_id)
{
		int i,j,k;
		i = j = k = 0;
		int rt;

		struct cr_route *route;
		while(i<length)
		{
			struct cr_floyd_matrix *m_element = (struct cr_floyd_matrix *)((char *)fm +
					(router_id*length+i)*sizeof(struct cr_floyd_matrix ));
			route = cr_route_head (route_table);
			rt = search_router_id_by_num(match, length, i);
			while(route)
			{
				if(rt == route->prefix.u.prefix6.s6_addr32[0])
				{
					m_element->metric = route->path.cost;
					//memcpy(&m_element->nexthop,&route->nexthop,sizeof(m_element->nexthop));

					for (k = 0; cr_nexthop_is_set (&route->nexthop[k]) &&k < CR_MULTI_PATH_LIMIT;k++)
					{
						m_element->nexthop[k].ifindex	= route->nexthop[k].ifindex;
						m_element->nexthop[k].router_id	= route->nexthop[k].router_id;
						m_element->nexthop[k].address	= route->nexthop[k].address;
					 }

					break;
				}
				else
					route = cr_route_next (route);
			}
			i+=1;
		}
}

void nexthop_choose(struct cr_floyd_matrix *fm,struct cr_floyd_match *matrix_match,int length,int lsdb_handler)
{
	int i = 0;
	int j=0;
	int k;
	struct cr_floyd_matrix *m_element	= NULL;
	int cur_ifindex;
	int min_ifindex;
	struct link_state_key link_key1;

	for(i=0;i<length;i++)
		{
			for(j=0;j<length;j++)
			{
				if(i==j)
				{
					continue;
				}
				m_element	= (struct cr_floyd_matrix *)((char *)fm + (i*length+j)*sizeof(struct cr_floyd_matrix));
				min_ifindex=m_element->nexthop[0].ifindex;
				for(k=0;cr_nexthop_is_set (&m_element->nexthop[k])&&k<CR_MULTI_PATH_LIMIT;k++)
				{

					cur_ifindex	= m_element->nexthop[k].ifindex;
					if(min_ifindex > cur_ifindex)
					{
						min_ifindex = cur_ifindex;
					}

				}
				link_key1.rt_id = cr_ddc_searchRouterIDByNum(matrix_match,length,i);
				link_key1.if_id = min_ifindex ;
				cr_lsdb_neighbour_info_find(&link_key1,lsdb_handler);
				m_element->nextHop = cr_ddc_searchNumByRouterID(matrix_match,length,link_key1.n_rt_id);

			}
		}
}

void show_route_table(struct cr_route_table *route_table, int router_id)
{
	struct cr_route *route;
	int i;
	printf("\n------The %d 's Result Route Table is----------------\n", router_id);
	printf("\n Total is %d\n",route_table->count);
	route = cr_route_head (route_table);
	while (route)
	{
		 printf("Destination is%d.%d.%d.%d",route->prefix.u.prefix6.s6_addr32[0], route->prefix.u.prefix6.s6_addr32[1], route->prefix.u.prefix6.s6_addr32[2], route->prefix.u.prefix6.s6_addr32[3]);
		 for (i = 0; cr_nexthop_is_set (&route->nexthop[i]) &&i < CR_MULTI_PATH_LIMIT; i++)
		 {
		   /* nexthop */
		  printf("  Nexthop is %d, Cost is %d",route->nexthop[i].ifindex, route->path.cost);
		 }
		  route = cr_route_next (route);
		  printf("\n");
	}
	  return;
}
